import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
// import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer'
import * as THREE from 'three'

export default class Labels {
  constructor(_viewer) {
    this.viewer = _viewer
  }

  /**
   * 添加 2d 标签
   * @param {string} id dom 的 id
   */
  addCss2dLabel(id) {
    if (!id || typeof id !== 'string' || !document.getElementById(id)) {
      throw Error('请传入正确的id')
    }
    const dom = document.getElementById(id)
    this.labelDom = dom
    this.label = new CSS2DObject(dom)
    this.viewer.labelDom = dom
    this.viewer.scene.add(this.label)
    return this.label
  }

  /**
   * 添加 canvas label
   */
  addCanvasLabel(opts = {}) {
    const canvas = this.createCanvas(opts)
    const texture = new THREE.CanvasTexture(canvas)
    const material = new THREE.SpriteMaterial({
      map: texture
    })
    const sprite = new THREE.Sprite(material)
    const { x, y, z } = opts.position || { x: 0, y: 0, z: 0 } // 精灵的位置
    sprite.position.set(x, y, z)
    const scale = opts.scale || 1 // 精灵的缩放大小
    sprite.scale.set(scale, scale, scale)
    sprite.name = opts.name || 'sprite'
    this.viewer.scene.add(sprite)

    sprite.canvas = canvas
    sprite.texture = texture

    return sprite
  }

  createCanvas(opts) {
    const baseSize = opts.baseSize || 300 // canvas 的大小
    const background = opts.background || 'rgba(0, 0, 0, 0.5)' // 背景填充色
    const divideX = opts.divideX || 1 // 背景宽度填充的比例
    const divideY = opts.divideY || 2 // 背景高度填充的比例
    const font = opts.font || '20px Arial' // canvas 字体
    const text = opts.text || '这是默认文本，请输入你要显示的文本...' // 显示的文本
    const textSpacing = opts.textSpacing || 30 // 每行两边的留白总和
    const ctxWidth = baseSize - textSpacing // 每行文字的宽度
    const fontColor = opts.fontColor || '#fff' // 字体颜色
    const lineHeight = opts.lineHeight || 30 // 每行文字的高度
    const x = opts.x || textSpacing / 2 // 文本绘制的x起始点
    const y = opts.y || 30 // 文本绘制的y起始点

    // 获取 canvas 对象
    const canvas = document.createElement('canvas')
    canvas.width = baseSize
    canvas.height = baseSize

    // 获取上下文环境对象 context
    const ctx = canvas.getContext('2d')
    ctx.fillStyle = background
    ctx.fillRect(0, 0, baseSize / divideX, baseSize / divideY)

    // 定义字体
    ctx.font = font

    // 绘制多行文本
    function drawRowsText(text, x, y) {
      const str = text.split('')
      let lastIdx = 0
      let lineWidth = 0
      ctx.fillStyle = fontColor

      for (let i = 0; i < str.length; i++) {
        lineWidth += ctx.measureText(str[i]).width
        if (lineWidth > ctxWidth) {
          ctx.fillText(text.substring(lastIdx, i), x, y)
          lineWidth = 0
          y += lineHeight
          lastIdx = i
        }
        if (i === str.length - 1) {
          ctx.fillText(text.substring(lastIdx, i + 1), x, y)
        }
      }
    }

    if (baseSize > ctx.measureText(text).width) {
      ctx.fillStyle = fontColor
      ctx.fillText(text, x, y)
    } else {
      drawRowsText(text, x, y)
    }

    return canvas
  }

  /**
   * 移除标签
   */
  removeLight() {
    this.viewer.scene.remove(this.label)
  }
}
